﻿<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>WebSocket Test</title>
</head>
<body>
    <script language="javascript" type="text/javascript">

        var wsUri = "ws://localhost:5000/chat";//"ws://61.160.234.21:44354/chat"; //
        var sid, frid, toId;
        var output;
        const data = {
            _waitingRemoteInvocations: new Map(),
            _commandInvocations: new Map(),
            onText: text => { },
            sessionId: 1,
            messages: [],
            sender: 0,
            senderSessionId:'',
            receiver: 0
        }

        function init() {
            output = document.getElementById("output");
            testWebSocket();
        }

        function testWebSocket() {
            sid = getQueryString("sid");
            if (!sid) {
                sid = 1;
            }
            frid = getQueryString("frid");
            if (!frid) {
                frid = 3
            }
            frsid = getQueryString('frsid');
            if (!frsid) {
                frsid = 'FFD5A36C538B7172';
            }
            toId = getQueryString("toId");
            if (!toId) {
                toId = 2;
            }
            data.sender = frid;
            data.senderSessionId = frsid;
            data.receiver = parseInt(toId)
            data.sessionId = parseInt(sid)

            console.log(data);

            elem("name").innerText = frid + " to " + toId;
            elem("btnSend").onclick = function (e) {
                send();
            }
            elem("msg").onkeydown = function (e) {
                if (e.keyCode == 13) {
                    send()
                }
            }

            websocket = new WebSocket(wsUri);
            websocket.onopen = function (evt) {
                //onOpen(evt)
                openSession()
            };
            websocket.onclose = function (evt) {
                onClose(evt)
            };
            websocket.onmessage = function (evt) {
                onMessage(evt)
            };
            websocket.onerror = function (evt) {
                onError(evt)
            };
        }

        function openSession() {
            callMessage('OpenSession', function (res) {
                console.log(res)
                data = JSON.parse(res)
                if (data.Error == 0) {
                    data.messages = data.Data.Messages;
                    data.sessionId = data.Data.SessionId;
                }
                console.log(data)
            }, data.senderSessionId, parseInt(toId))
        }

        function onOpen(evt) {
            writeToScreen("CONNECTED");
            doSend(JSON.stringify({ fromId: sid, toId: toId, MessageType: 'text', content: 'hello,I am opening for you!' }));
        }

        function onClose(evt) {
            writeToScreen("DISCONNECTED");
        }

        function onMessage(evt) {
            //console.log(evt)
            //onReceiveMessage(JSON.parse(evt.data))
            writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data + '</span>');
            //websocket.close();
        }

        function onError(evt) {
            writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
        }

        function doSend(message) {
            writeToScreen("SENT: " + message);
            //websocket.send(message);
            sendMessage(0, message)
        }

        function sendMessage(messageType, data) {
            var res = { messageType: messageType, data: JSON.stringify(data) }
            websocket.send(JSON.stringify(res))
        }

        function callMessage(methodName, callback, ...args) {
            const identity = uuid();
            console.log(args)
            sendMessage(1, { methodName: methodName, identifier: identity, arguments: args || [] });
        }

        function writeToScreen(message) {
            var pre = document.createElement("p");
            pre.style.wordWrap = "break-word";
            pre.innerHTML = message;
            output.appendChild(pre);
            window.scrollTo(0,100000)
        }

        function getQueryString(name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            var r = window.location.search.substr(1).match(reg);
            if (r != null) return unescape(r[2]); return null;
        }

        function elem(id) {
            return document.getElementById(id);
        }

        function send() {
            var ds = document.getElementById('msg');
            var msg = elem("msg").value;
            elem("msg").value = '';
            console.log(data)
            doSend({ sessionId: data.sessionId, senderId: data.sender, senderSessionId: data.senderSessionId, receiverId: data.receiver, message: msg })
        }

        function uuid() {
            var s = [];
            var hexDigits = "0123456789abcdef";
            for (var i = 0; i < 36; i++) {
                s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
            }
            s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
            s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
            s[8] = s[13] = s[18] = s[23] = "-";

            var uuid = s.join("");
            return uuid;
        }

        function onReceiveMessage(res) {
            console.log("onsocketmessage: " + res.data)
            const jres = JSON.parse(res.data)
            if (jres.messageType == 0) { //text
                data.onText(jres.data)
            } else if (jres.messageType == 1) { //methodinvocation
                const invocationDes = JSON.parse(jres.data)
                if (data._commandInvocations.has(invocationDes.methodName)) {
                    const method = data._commandInvocation.get(invocationDes.methodName)
                    if (invocationDes.identifier == '') { //无标识 则不需返回值
                        try {
                            method(invocationDes.arguments || [])
                        } catch (e) {
                            console.log('on method invocation message failed', e)
                        }
                    } else {
                        let result = null;
                        let exception = null;
                        try {
                            result = method(invocationDes.arguments || [])
                        } catch (e) {
                            console.log('on method invocation message failed', e)
                            exception = e.toString()
                        }
                        data.returnMessage({
                            identifier: invocationDes.identifier,
                            result: result,
                            exception: exception
                        })
                    }
                }
            } else if (jres.messageType == 2) { //connection event
                data.connectionId = jres.data
            } else if (jres.messageType == 3) { //method return
                const invocationResult = JSON.parse(jres.data)
                if (data._waitingRemoteInvocations.has(invocationResult.identifier)) {
                    try {
                        var callback = data._waitingRemoteInvocations.get(invocationResult.identifier)
                        data._waitingRemoteInvocations.delete(invocationResult.identifier)
                        callback(invocationResult.result, invocationResult.exception)
                    }
                    catch (e) {
                        console.log('method callback failed', e)
                    }
                }
            }
        }

        window.addEventListener("load", init, false);
    </script>
    <h2>WebSocket Test</h2>
    <h3 id="name"></h3>
    <div id="output"></div>
    <hr />
    <input type="text" id="msg" placeholder="send message" />
    <button id="btnSend" onclick="send">发送</button>
    <!--<input type="button" id="btnSend" value="发送" />-->
</body>
</html>